import { ViewIcon, ViewOffIcon } from '@chakra-ui/icons';
import {
  Box,
  Button,
  Flex,
  FormControl,
  FormErrorMessage,
  FormLabel,
  Heading,
  Input,
  InputGroup,
  InputRightElement,
  Link,
  Stack,
  Text,
  useColorModeValue,
  useToast,
} from '@chakra-ui/react';
import { $authToken } from '@tourfly/api';

import { Field, FieldProps, Formik } from 'formik';
import { parse } from 'qs';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
  Link as ReactRouterLink,
  useLocation,
  useNavigate,
} from 'react-router-dom';

import userService from '@/api/user.service';
import { CustomLoader } from '@/common/components/NewLoading';
import { getToken, removeToken } from '@/common/utils';

import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { setIsLogin, setUserInfo } from '@/store/user';

interface RegistryForm {
  username: string;
  email: string;
  mobile: string;
  password: string;
  recommendCode: string;
}
export default function SignupCard() {
  const { t } = useTranslation();
  const toast = useToast();
  const [showPassword, setShowPassword] = useState(false);
  const [checkTokenLoading, setCheckTokenLoading] = useState(true);
  const dispatch = useAppDispatch();
  const { isLogin, loading } = useAppSelector((state) => state.user);
  const navigate = useNavigate();
  const { search } = useLocation();
  const code = parse(search.slice(1)).code?.toString();

  const bg = useColorModeValue('white', 'base.800');

  useEffect(() => {
    isLogin && navigate('/');

    /** 没有token的情况 */
    if (getToken()) {
      userService
        .getUserInfo()
        .then((res) => {
          if (!res.rt || !res.rt.token || !res.rt.userInfo) {
            removeToken();
            $authToken.set(undefined);
            setCheckTokenLoading(false);
          } else {
            dispatch(setUserInfo(res.rt.userInfo));
            dispatch(setIsLogin(true));
            navigate('/');
          }
        })
        .catch(() => {
          setCheckTokenLoading(false);
          removeToken();
          $authToken.set(undefined);
        });
    } else {
      setCheckTokenLoading(false);
    }
  }, [dispatch, isLogin, navigate]);

  const handleRegistry = async (values: RegistryForm) => {
    try {
      const { code } = await userService.registry(values);
      if (Number(code) === 200) {
        toast({
          position: 'top',
          description: '注册成功',
          status: 'success',
          duration: 3000,
          isClosable: true,
        });
        navigate('/signin');
      }
    } catch (e) {
      console.log(e);
    }
  };

  return (
    <Flex align="center" justify="center">
      {checkTokenLoading ? (
        <CustomLoader />
      ) : (
        <Stack
          spacing={8}
          mx="auto"
          maxW="lg"
          minW={{ md: 'md' }}
          py={12}
          px={6}
        >
          <Stack align="center">
            <Heading fontSize="4xl" textAlign="center">
              {t('auth.createAccount')}
            </Heading>
            <Text fontSize="lg" color="gray.600">
              {t('auth.enjoyFeature')}
            </Text>
          </Stack>
          <Box rounded="lg" bg={bg} boxShadow="lg" p={8}>
            <Formik
              initialValues={{
                username: '',
                email: '',
                mobile: '',
                password: '',
                recommendCode: code || '',
              }}
              onSubmit={(values) => {
                handleRegistry(values);
              }}
            >
              {({ handleSubmit, errors, touched }) => (
                <form onSubmit={handleSubmit}>
                  <Stack spacing={4}>
                    <Field
                      name="username"
                      validate={(value: string) => {
                        let error;
                        if (!value) {
                          error = 'Username isRequired';
                        }
                        return error;
                      }}
                    >
                      {({ field }: FieldProps) => (
                        <FormControl
                          isRequired
                          isInvalid={Boolean(
                            errors.username && touched.username
                          )}
                        >
                          <FormLabel fontWeight="600" htmlFor="username">
                            {t('profile.username')}
                          </FormLabel>
                          <Input
                            id="username"
                            type="text"
                            variant="filled"
                            {...field}
                            placeholder={t('auth.createUsername')}
                          />
                          <FormErrorMessage>
                            {errors.username as string}
                          </FormErrorMessage>
                        </FormControl>
                      )}
                    </Field>
                    <Field
                      name="mobile"
                      validate={(value: string) => {
                        let error;
                        if (!value) {
                          error = t('auth.mobileRequired');
                        }
                        if (value && !/^1[3456789]\d{9}$/.test(value)) {
                          error = t('auth.invalidMobile');
                        }
                        return error;
                      }}
                    >
                      {({ field }: FieldProps) => (
                        <FormControl
                          isRequired
                          isInvalid={Boolean(errors.mobile && touched.mobile)}
                        >
                          <FormLabel fontWeight="600" htmlFor="mobile">
                            {t('profile.mobile')}
                          </FormLabel>
                          <Input
                            id="mobile"
                            type="text"
                            variant="filled"
                            {...field}
                            placeholder={t('auth.mobilePlaceholder')}
                          />
                          <FormErrorMessage>
                            {errors.mobile as string}
                          </FormErrorMessage>
                        </FormControl>
                      )}
                    </Field>
                    <Field
                      name="email"
                      validate={(value: string) => {
                        let error;
                        if (
                          value &&
                          !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(
                            value
                          )
                        ) {
                          error = t('auth.invalidEmail');
                        }
                        return error;
                      }}
                    >
                      {({ field }: FieldProps) => (
                        <FormControl isInvalid={Boolean(errors.email)}>
                          <FormLabel fontWeight="600" htmlFor="email">
                            {t('profile.email')}
                          </FormLabel>
                          <Input
                            id="email"
                            type="email"
                            variant="filled"
                            {...field}
                            placeholder={t('auth.emailPlaceholder')}
                          />
                          <FormErrorMessage>
                            {errors.email as string}
                          </FormErrorMessage>
                        </FormControl>
                      )}
                    </Field>
                    <Field
                      name="password"
                      validate={(value: string) => {
                        let error;
                        if (value.length < 6) {
                          error = t('auth.passwordError');
                        }
                        return error;
                      }}
                    >
                      {({ field }: FieldProps) => (
                        <FormControl
                          isRequired
                          isInvalid={Boolean(
                            errors.password && touched.password
                          )}
                        >
                          <FormLabel fontWeight="600" htmlFor="password">
                            {t('profile.password')}
                          </FormLabel>

                          <InputGroup>
                            <Input
                              id="password"
                              type={showPassword ? 'text' : 'password'}
                              variant="filled"
                              {...field}
                              placeholder={t('auth.passwordPlaceholder')}
                            />
                            <InputRightElement
                              cursor="pointer"
                              onClick={() => setShowPassword(!showPassword)}
                            >
                              {!showPassword ? <ViewOffIcon /> : <ViewIcon />}
                            </InputRightElement>
                          </InputGroup>
                          <FormErrorMessage>
                            {errors.password as string}
                          </FormErrorMessage>
                        </FormControl>
                      )}
                    </Field>
                    <Field
                      name="recommendCode"
                      validate={(value: string) => {
                        let error;
                        if (!value) {
                          error = t('auth.codeRequired');
                        }
                        if (value && !/^[A-Z0-9]{6}$/i.test(value)) {
                          error = t('auth.codeError');
                        }
                        return error;
                      }}
                    >
                      {({ field }: FieldProps) => (
                        <FormControl
                          isRequired
                          isInvalid={Boolean(
                            errors.recommendCode && touched.recommendCode
                          )}
                        >
                          <FormLabel fontWeight="600" htmlFor="recommendCode">
                            {t('profile.recommendCode')}
                          </FormLabel>
                          <Input
                            id="recommendCode"
                            type="text"
                            variant="filled"
                            {...field}
                            placeholder={t('auth.codePlaceholder')}
                          />
                          <FormErrorMessage>
                            {errors.recommendCode as string}
                          </FormErrorMessage>
                        </FormControl>
                      )}
                    </Field>
                    <Stack spacing={10} pt="3">
                      <Button
                        bg="base.700"
                        isLoading={loading}
                        loadingText="Submitting"
                        type="submit"
                      >
                        {t('auth.signup')}
                      </Button>
                    </Stack>
                  </Stack>
                </form>
              )}
            </Formik>
            <Stack pt={6}>
              <Text align="center">
                {t('auth.haveAccount')}{' '}
                <Link as={ReactRouterLink} color="blue.400" to="/signin">
                  {t('auth.signin')}
                </Link>
              </Text>
            </Stack>
          </Box>
        </Stack>
      )}
    </Flex>
  );
}
